package project

import (
	"context"
	"gf-assistant/internal/common/consts"
	"gf-assistant/internal/common/factory"
	"gf-assistant/internal/project/parameter"
	"github.com/gogf/gf/v2/util/gconv"
	"reflect"
)

type ProjectService struct {
	projectDao string
	memberDao  string
	taskDao    string
}

func init() {
	projectService := ProjectService{
		projectDao: "project.ProjectDao",
		memberDao:  "project.MemberDao",
		taskDao:    "project.TaskDao",
	}
	factory.Put(reflect.TypeOf(projectService).String(), &projectService)
}
func (s *ProjectService) GetProjectDao() *ProjectDao {
	return factory.Get(s.projectDao).(*ProjectDao)
}
func (s *ProjectService) GetMemberDao() *MemberDao {
	return factory.Get(s.memberDao).(*MemberDao)
}
func (s *ProjectService) GetTaskDao() *TaskDao {
	return factory.Get(s.taskDao).(*TaskDao)
}
func (s *ProjectService) GetProject(ctx context.Context, req *parameter.GetProjectReq) (res *parameter.GetProjectRes) {
	return s.GetProjectDao().GetProject(ctx, req)
}
func (s *ProjectService) ListProject(ctx context.Context, req *parameter.ListProjectReq) (res *parameter.ListProjectRes) {
	if req.Page <= 1 {
		req.Page = 1
	}
	if req.Size == 0 {
		req.Size = 10
	}
	req.SetUserId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))

	projects := s.GetProjectDao().ListProject(ctx, req)
	count := s.GetProjectDao().CountProject(ctx, req)
	res = &parameter.ListProjectRes{
		Total:  count,
		Detail: projects,
	}
	return res
}
func (s *ProjectService) CreateProject(ctx context.Context, req *parameter.CreateProjectReq) (res *parameter.CreateProjectRes) {
	req.SetUserId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))
	//判断项目编码是否已经存在，存在的话，不允许新增
	project := s.GetProjectDao().GetByProjectCode(ctx, req.ProjectCode)
	if project != nil {
		panic("项目编码已经存在，请重新录入项目编码")
	}
	//开启事务
	tx, err := s.GetProjectDao().DB().Begin(ctx)
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			panic("项目已经存在")
		} else {
			err := tx.Commit()
			if err != nil {
				return
			}
		}
	}()
	res, err = s.GetProjectDao().CreateProject(tx, req)
	createMemberReq := parameter.CreateMemberReq{
		UserIds:    gconv.String(req.GetUserId()),
		ProjectId:  res.ProjectId,
		PositionId: 1,
		Remark:     "自动添加项目成员-项目经理",
	}
	createMemberReq.SetOperatorId(req.GetUserId())
	s.GetMemberDao().CreateMember(tx, &createMemberReq)
	createTaskReq := parameter.CreateTaskReq{
		ParentId:  0,
		ProjectId: res.ProjectId,
		TaskName:  req.ProjectName,
		TaskCode:  req.ProjectCode + "-001",
		Remark:    "自动添加项目成员-项目经理",
	}
	createTaskReq.SetOperatorId(req.GetUserId())
	_, _ = s.GetTaskDao().CreateTask(tx, &createTaskReq)
	return res
}
func (s *ProjectService) SaveProject(ctx context.Context, req *parameter.SaveProjectReq) (res *parameter.SaveProjectRes) {
	req.SetUserId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))
	//判断项目编码是否已经存在，存在的话，不允许新增
	project := s.GetProjectDao().GetByProjectCode(ctx, req.ProjectCode)
	if project != nil && project.ProjectId != req.ProjectId {
		panic("项目编码已经存在，请重新录入项目编码")
	}
	//开启事务
	tx, err := s.GetProjectDao().DB().Begin(ctx)
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			panic("修改项目失败")
		} else {
			err := tx.Commit()
			if err != nil {
				return
			}
		}
	}()
	s.GetProjectDao().SaveProject(tx, req)
	return &parameter.SaveProjectRes{ProjectId: req.ProjectId}
}
func (s *ProjectService) DeleteProject(ctx context.Context, req *parameter.DeleteProjectReq) (res *parameter.DeleteProjectRes) {
	req.SetUserId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))
	tx, err := s.GetProjectDao().DB().Begin(ctx)
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			panic("删除项目失败")
		} else {
			err := tx.Commit()
			if err != nil {
				return
			}
		}
	}()
	res, err = s.GetProjectDao().DeleteProject(tx, req)
	return res
}
func (s *ProjectService) GetProjectTree(ctx context.Context, req *parameter.GetProjectTreeReq) (res *parameter.GetProjectTreeRes) {
	results := make([]*parameter.ProjectTreeRes, 0)
	req.SetUserId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))
	projects := s.GetProjectDao().GetProjectTree(ctx, req)
	root := &parameter.ProjectTreeRes{
		Id:       0,
		PId:      0,
		Title:    "我参与的项目",
		Spread:   true,
		Children: projects,
	}
	results = append(results, root)
	return &parameter.GetProjectTreeRes{
		Detail: results,
	}
}
func (s *ProjectService) GetProjectCombox(ctx context.Context, req *parameter.GetProjectComboxReq) (res *parameter.GetProjectComboxRes) {
	req.SetUserId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))
	projects := s.GetProjectDao().GetProjectCombox(ctx, req)
	for index, v := range projects {
		if index == 1 {
			v.Selected = true
		}
	}
	return &parameter.GetProjectComboxRes{
		Detail: projects,
	}
}
